package cn.maihe.elg.operation.supports.electronicseal.anne.utils.annesign;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.Set;

public class ValidateUtils {

    private ValidateUtils() {
    }

    /**
     * hibernate validate impl，只抛出第一个异常信息
     *
     * @param t
     * @param <T>
     * @return
     * @throws ValidateException
     */
    public static <T> boolean validateOnce(T t, Class<?>... classes) throws ValidateException {
        Set<String> errorMessages = validateParameters(t);
        if (CollectionUtils.isNotEmpty(errorMessages)) {
            throw new ValidateException(Lists.newArrayList(errorMessages).get(0));
        }

        return true;
    }


    /**
     * hibernate validate impl，抛出所有异常信息
     *
     * @param t
     * @param <T>
     * @return
     * @throws ValidateException
     */
    public static <T> boolean validate(T t, Class<?>... classes) throws ValidateException {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();
        Set<ConstraintViolation<T>> constraintViolations = validator.validate(t, classes);

        Set<String> errorMessages = Sets.newTreeSet();

        if (CollectionUtils.isNotEmpty(constraintViolations)) {
            constraintViolations.forEach(e -> errorMessages.add(e.getMessage()));
            throw new ValidateException(StringUtils.join(errorMessages, "; "));
        }

        return true;
    }


    /**
     * @param t
     * @param classes
     * @param <T>
     * @return
     */
    public static <T> Set<String> validateParameters(T t, Class<?>... classes) {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();
        Set<ConstraintViolation<T>> constraintViolations = validator.validate(t, classes);

        Set<String> errorMessages = Sets.newTreeSet();

        if (CollectionUtils.isNotEmpty(constraintViolations)) {
            constraintViolations.forEach(e -> errorMessages.add(e.getMessage()));
        }

        return errorMessages;
    }

    /**
     * Check the Set and return the errors that it contains.
     *
     * @param errors
     * @return Errors found
     * @since Jan 15, 2014
     */
    public static <T> String returnErrors(final Set<ConstraintViolation<T>> errors) {
        final StringBuilder builder = new StringBuilder();
        for (final ConstraintViolation<T> error : errors) {
            builder.append(error.getMessage()).append("\n");
        }
        return builder.toString();
    }
}
